package com.diankangwo.controller;

import com.diankangwo.constant.resultMsg;
import com.diankangwo.dao.InvitationDAO;
import com.diankangwo.dao.PhoneAndCodeDAO;
import com.diankangwo.dao.UserDAO;
import com.diankangwo.domain.Invitation;
import com.diankangwo.domain.UserInfo;
import com.diankangwo.util.BankUtil;
import com.diankangwo.util.GuidUtil;
import com.diankangwo.util.TokenUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 用戶控制器
 *
 * @author xiaoyu
 */
@Controller
@RequestMapping("/users")
@Api(description = "用户")
public class UserController {
    @Autowired
    private UserDAO userDao;

    @Resource
    private ReflectionSaltSource saltSource;

    @Resource
    private ShaPasswordEncoder passwordEncoder;

    @Autowired
    private InvitationDAO ivtDao;

    @Autowired
    public PhoneAndCodeDAO phoneAndCodeDao;

    /**
     * 获取指定用户的公开信息
     *
     * @param id 用户UID
     * @return
     */
    @ApiOperation(value = "获取指定用户的公开信息", notes = "")
    @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Integer")
    @ResponseBody
    @RequestMapping(value = "/userinfo_show", method = RequestMethod.GET)
    public String show(Integer id) {
        UserInfo user = userDao.find(id);
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            code = "1";
            msg = "查询成功！";
            user.setPassword("");
            user.setSalt_value("");
        } else {
            code = "1";
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, user);
    }

    /**
     * 修改手机号
     *
     * @param msgCode       短信验证码
     * @param newTel        新手机号
     * @param accessToken   token
     * @param newTelMsgCode 新手机号验证码
     * @return json
     */
    @ApiOperation(value = "修改密码", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "newTel", value = "新手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "newPassword", value = "新密码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "msgCode", value = "短信验证码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "newTelMsgCode", value = "新手机号验证码", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/userinfo_updatePhone", method = RequestMethod.POST)
    public String updatePhone(String msgCode, String newTel, String newTelMsgCode, String accessToken,
                              HttpServletRequest req) {
        UserInfo user = userDao.getUserByToken(accessToken);
        user.setTel(newTel);
        user.setAccessToken(TokenUtils.createToken(user.getUid(), req));
        String code = "2";
        String msg = "处理异常！";
        if (userDao.updateUser(user)) {
            code = "1";
            msg = "更新成功！";
            user.setPassword("");
            user.setSalt_value("");
        } else {
            msg = "系统异常，更新失败！";
        }
        return resultMsg.mapToJson(code, msg, "");
    }

    /**
     * 修改密码
     *
     * @param msgCode     短信验证码
     * @param newPassword 新密码
     * @param tel         手机号
     * @return json
     */
    @ApiOperation(value = "修改密码", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tel", value = "电话号码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "newPassword", value = "新密码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "msgCode", value = "短信验证码", required = true, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/userinfo_updatePassWord", method = RequestMethod.POST)
    public String updatePassWord(String tel, String newPassword, String msgCode, HttpServletRequest req) {
        UserInfo user = userDao.getUserByTel(tel);
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            if (user.getTel().equals(tel)) {
                if (msgCode.equals(req.getSession(false).getAttribute(tel).toString())) {
                    user.setSalt_value(System.currentTimeMillis() + "");
                    newPassword = passwordEncoder.encodePassword(newPassword, saltSource.getSalt(user));
                    user.setPassword(newPassword);
                    if (userDao.saveOrUpdate(user) != null) {
                        code = "1";
                        msg = "更新密码成功！";
                        user.setPassword("");
                        user.setSalt_value("");
                    } else {
                        msg = "系统异常，更新失败！";
                    }
                } else {
                    msg = "验证码不正确！";
                }
            }
        } else {
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, user);
    }

    /**
     * 修改个人资料
     *
     * @param profileImageUrl 头像
     * @param username        用户名
     * @param description     简介
     * @param accessToken     token
     * @param gender          性别
     * @return
     */
    @ApiOperation(value = "修改个人资料", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "profileImageUrl", value = "头像", required = true, dataType = "String"),
            @ApiImplicitParam(name = "description", value = "简介", required = true, dataType = "String"),
            @ApiImplicitParam(name = "gender", value = "性别", required = true, dataType = "Boolean"),
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/updateInfo", method = RequestMethod.POST)
    public String updateUser(String accessToken, String profileImageUrl, String description, Boolean gender, String
            username) {
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            if (!username.equals("") && username != null) {
                user.setUsername(username);
            }
            if (!description.equals("") && description != null) {
                user.setDescription(description);
            }
            if (!gender.equals("") && gender != null) {
                user.setGender(gender);
            }
            if (!profileImageUrl.equals("") && profileImageUrl != null) {
                user.setProfileImageUrl(profileImageUrl);
            }
            if (userDao.saveOrUpdate(user) != null) {
                code = "1";
                msg = "更新成功！";
                user.setPassword("");
                user.setSalt_value("");
            } else {
                msg = "系统异常，修改失败！";
            }
        } else {
            msg = "无效的token!";
        }
        user.setPassword("");
        user.setSalt_value("");
        return resultMsg.mapToJson(code, msg, user);
    }

    /**
     * 修改银行卡资料
     *
     * @param accessToken
     * @param req
     * @param msgCode
     * @param BankCardNo
     * @param name
     * @return
     */
    @ApiOperation(value = "修改银行卡资料", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "msgCode", value = "短信验证码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "BankCardNo", value = "银行卡账号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "name", value = "姓名", required = true, dataType = "String")
    })
    @ResponseBody
    @RequestMapping(value = "/updateBankInfo", method = RequestMethod.POST)
    public String updateBankInfo(String accessToken, HttpServletRequest req, String msgCode, String BankCardNo, String name) {
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "操作异常！";
        if (BankUtil.getNameOfBank(BankCardNo).equals("")) {
            msg = "银行卡号不正确！";
            return resultMsg.mapToJson(code, msg, user);
        }
        try {
            if (user != null) {
                user.setName(name);
                user.setBankCardNo(BankCardNo);
                user.setBankCardType(BankUtil.getNameOfBank(BankCardNo));
                String old = req.getSession(false).getAttribute(user.getTel()).toString();
                //判断验证码时候正确
                if (msgCode.equals(old)) {
                    if (userDao.saveOrUpdate(user) != null) {
                        code = "1";
                        msg = "更新成功！";
                    } else {
                        msg = "系统异常，修改失败！";
                    }
                } else {
                    msg = "验证码不正确！";
                }
                user.setPassword("");
                user.setSalt_value("");
            } else {
                msg = "为获取到用户信息！";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMsg.mapToJson(code, msg, user);
    }

    /**
     * 注销登陆
     *
     * @param accessToken token
     * @param getuiCID    个推ID
     * @return
     */
    @ApiOperation(value = "注销登陆", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accessToken", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "getuiCID", value = "个推ID", required = true, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/userinfo_log_out", method = RequestMethod.POST)
    public String log_out(String accessToken, String getuiCID) {
        UserInfo user = userDao.getUserByToken(accessToken);
        String code = "2";
        String msg = "注销异常！";
        if (user != null) {
            code = "1";
            msg = "注销成功！";
            user.setPassword("");
            user.setSalt_value("");
        }
        return resultMsg.mapToJson(code, msg, "");
    }

    /**
     * 用户登录
     *
     * @param username  用户名
     * @param password  密码
     * @param getui_cid 个推CID
     * @return
     */
    @ApiOperation(value = "用户登录", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "getui_cid", value = "个推ID", required = true, dataType = "Integer")
    })
    @ResponseBody
    @RequestMapping(value = "/users_login", method = RequestMethod.POST)
    public String login(String username, String password, String getui_cid) {
        UserInfo user = userDao.getUserByTelAndEnabled(username);
        String code = "2";
        String msg = "处理异常！";
        if (user != null) {
            password = passwordEncoder.encodePassword(password, user.getSalt_value());
            if (user.getPassword().equals(password)) {
                user.setGetui_cid(getui_cid);
                if (userDao.updateUser(user)) {
                    code = "1";
                    msg = "查询成功！";
                }
            } else {
                msg = "密码错误!";
            }
            user.setPassword(null);
            user.setSalt_value(null);
        } else {
            msg = "未查询到用户信息！";
        }
        return resultMsg.mapToJson(code, msg, user);
    }

    /**
     * 注册
     *
     * @param tel      电话号码
     * @param password 密码
     * @param msgCode  短信验证码
     * @return json
     */
    @ApiOperation(value = "注册", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tel", value = "电话号码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "msgCode", value = "短信验证码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "invitedUID", value = "邀请码", required = true, dataType = "Integer"),
    })
    @ResponseBody
    @RequestMapping(value = "/userinfo_register", method = RequestMethod.POST)
    public String register(String tel, String password, String msgCode, Integer invitedUID, HttpServletRequest req) {
        UserInfo user = new UserInfo();
        String code = "2";
        String msg = "处理异常！";
        UserInfo user2 = userDao.find(invitedUID);
        if (invitedUID == null || user2 == null) {
            msg = "无效的邀请码！";
            return resultMsg.mapToJson(code, msg, null);
        }

        if (!user2.isPort()) {
            msg = "无效的邀请码！";
            return resultMsg.mapToJson(code, msg, null);
        }
        user.setIntegral(0);
        user.setTel(tel);
        user.setUid(GuidUtil.getGuid());
        user.setUsername(tel);
        user.setEnabled(true);
        user.setSalt_value(System.currentTimeMillis() + "");
        password = passwordEncoder.encodePassword(password, saltSource.getSalt(user));
        user.setPassword(password);
        user.setAccessToken(TokenUtils.createToken(user.getUid(), req));
        user.setParentId(invitedUID);
        user.setCreatedate(new Date());
        boolean old = phoneAndCodeDao.findByCode(tel, msgCode);
        if (userDao.getUserByTel(tel) != null) {
            msg = "该手机号码已注册！";
        } else {
            //判断验证码时候正确
            if (old) {
                if (userDao.saveOrUpdate(user) != null) {
                    code = "1";
                    msg = "注册成功！";
                    user.setPassword("");
                    user.setSalt_value("");
                    Invitation ivn = new Invitation();
                    ivn.setDate(new Date());
                    ivn.setFuid(userDao.find(invitedUID).getUid());
                    ivn.setUid(user.getId());
                    ivn.setUserName(user.getUsername());
                    ivn.setSpending_total(0f);
                    ivn.setMy_earnings(0f);
                    ivtDao.saveOrUpdate(ivn);
                } else {
                    msg = "系统异常，注册失败！";
                }
            } else {
                msg = "验证码不正确！";
            }

        }
        return resultMsg.mapToJson(code, msg, user);
    }

}